{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Grover's Algorithm and Amplitude Amplification\n",
    "\n",
    "Grover's algorithm is one of the most famous quantum algorithms introduced by Lov Grover in 1996 \\[1\\]. It has initially been proposed for unstructured search problems, i.e. for finding a marked element in a unstructured database. However, Grover's algorithm is now a subroutine to several other algorithms, such as Grover Adaptive Search \\[2\\]. For the details of Grover's algorithm, please see [Grover's Algorithm](https://qiskit.org/textbook/ch-algorithms/grover.html) in the Qiskit textbook.\n",
    "\n",
    "Qiskit implements Grover's algorithm in the `Grover` class. This class also includes the generalized version, Amplitude Amplification \\[3\\], and allows setting individual iterations and other meta-settings to Grover's algorithm.\n",
    "\n",
    "**References:**\n",
    "\n",
    "\\[1\\]: L. K. Grover, A fast quantum mechanical algorithm for database search. Proceedings 28th Annual Symposium on\n",
    "the Theory of Computing (STOC) 1996, pp. 212-219. https://arxiv.org/abs/quant-ph/9605043\n",
    "\n",
    "\\[2\\]: A. Gilliam, S. Woerner, C. Gonciulea, Grover Adaptive Search for Constrained Polynomial Binary Optimization.\n",
    "https://arxiv.org/abs/1912.04088\n",
    "\n",
    "\n",
    "\\[3\\]: Brassard, G., Hoyer, P., Mosca, M., & Tapp, A. (2000). Quantum Amplitude Amplification and Estimation. http://arxiv.org/abs/quant-ph/0005055"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Grover's algorithm\n",
    "\n",
    "Grover's algorithm uses the Grover operator $\\mathcal{Q}$ to amplify the amplitudes of the good states:\n",
    "\n",
    "$$\n",
    "    \\mathcal{Q} = \\mathcal{A}\\mathcal{S_0}\\mathcal{A}^\\dagger \\mathcal{S_f}\n",
    "$$\n",
    "\n",
    "Here, \n",
    "* $\\mathcal{A}$ is the initial search state for the algorithm, which is just Hadamards, $H^{\\otimes n}$ for the textbook Grover search, but can be more elaborate for Amplitude Amplification\n",
    "* $\\mathcal{S_0}$ is the reflection about the all 0 state\n",
    "$$\n",
    "    |x\\rangle \\mapsto \\begin{cases} -|x\\rangle, &x \\neq 0 \\\\ |x\\rangle, &x = 0\\end{cases}\n",
    "$$\n",
    "* $\\mathcal{S_f}$ is the oracle that applies \n",
    "$$\n",
    "    |x\\rangle \\mapsto (-1)^{f(x)}|x\\rangle\n",
    "$$ \n",
    "&nbsp;&nbsp;&nbsp;&nbsp;　where $f(x)$ is 1 if $x$ is a good state and otherwise 0.\n",
    "\n",
    "In a nutshell, Grover's algorithm applies different powers of $\\mathcal{Q}$ and after each execution checks whether a good solution has been found. \n",
    "\n",
    "\n",
    "### Running Grover's algorithm \n",
    "\n",
    "To run Grover's algorithm with the `Grover` class, firstly, we need to specify an oracle for the circuit of Grover's algorithm. In the following example, we use `QuantumCircuit` as the oracle of Grover's algorithm. However, there are several other class that we can use as the oracle of Grover's algorithm. We talk about them later in this tutorial.\n",
    "\n",
    "Note that the oracle for `Grover` must be a _phase-flip_ oracle. That is, it multiplies the amplitudes of the of \"good states\" by a factor of $-1$. We explain later how to convert a _bit-flip_ oracle to a phase-flip oracle. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f359572eba8>"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from qiskit import QuantumCircuit\n",
    "from qiskit.aqua.algorithms import Grover\n",
    "\n",
    "# the state we desire to find is '11'\n",
    "good_state = ['11']\n",
    "\n",
    "# specify the oracle that marks the state '11' as a good solution\n",
    "oracle = QuantumCircuit(2)\n",
    "oracle.cz(0, 1)\n",
    "\n",
    "# define Grover's algorithm\n",
    "grover = Grover(oracle=oracle, good_state=good_state)\n",
    "\n",
    "# now we can have a look at the Grover operator that is used in running the algorithm\n",
    "grover.grover_operator.draw(output='mpl')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Then, we specify a backend and call the `run` method of `Grover` with a backend to execute the circuits. The returned result type is a `GroverResult`. \n",
    "\n",
    "If the search was successful, the `oracle_evaluation` attribute of the result will be `True`. In this case, the most sampled measurement, `top_measurement`, is one of the \"good states\". Otherwise, `oracle_evaluation` will be False.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Result type: <class 'qiskit.aqua.algorithms.amplitude_amplifiers.grover.GroverResult'>\n",
      "\n",
      "Success!\n",
      "Top measurement: 11\n"
     ]
    }
   ],
   "source": [
    "from qiskit import Aer\n",
    "from qiskit.aqua import QuantumInstance\n",
    "\n",
    "qasm_simulator = Aer.get_backend('qasm_simulator')\n",
    "result = grover.run(quantum_instance=qasm_simulator)\n",
    "print('Result type:', type(result))\n",
    "print()\n",
    "print('Success!' if result.oracle_evaluation else 'Failure!')\n",
    "print('Top measurement:', result.top_measurement)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In the example, the result of `top_measurement` is `11` which is one of \"good state\". Thus, we succeeded to find the answer by using `Grover`."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Using the different types of classes as the oracle of `Grover`\n",
    "In the above example, we used `QuantumCircuit` as the oracle of `Grover`. \n",
    "However, we can also use `qiskit.aqua.components.oracles.Oracle`, and `qiskit.quantum_info.Statevector` as oracles.\n",
    "All the following examples are when $|11\\rangle$ is \"good state\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Result type: <class 'qiskit.aqua.algorithms.amplitude_amplifiers.grover.GroverResult'>\n",
      "\n",
      "Success!\n",
      "Top measurement: 11\n"
     ]
    }
   ],
   "source": [
    "from qiskit.quantum_info import Statevector\n",
    "oracle = Statevector.from_label('11')\n",
    "grover = Grover(oracle=oracle, good_state=['11'])\n",
    "\n",
    "result = grover.run(quantum_instance=qasm_simulator)\n",
    "print('Result type:', type(result))\n",
    "print()\n",
    "print('Success!' if result.oracle_evaluation else 'Failure!')\n",
    "print('Top measurement:', result.top_measurement)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Internally, the statevector is mapped to a quantum circuit:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f35d7614710>"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grover.grover_operator.oracle.draw(output='mpl')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The `Oracle` components in Qiskit Aqua allow for an easy construction of more complex oracles.\n",
    "The `Oracle` type has the interesting subclasses:\n",
    "* `LogicalExpressionOracle`: for parsing logical expressions such as `'~a | b'`. This is especially useful for solving 3-SAT problems and is shown in the accompanying [Grover Examples](08_grover_examples.ipynb) tutorial.\n",
    "* `TrutheTableOracle`: for converting binary truth tables to circuits \n",
    "\n",
    "Here we'll use the `LogicalExpressionOracle` for the simple example of finding the state $|11\\rangle$, which corresponds to `'a & b'`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAToAAACvCAYAAABtnhIYAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMS4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvNQv5yAAADqJJREFUeJzt3X1wFPdhxvHv7UmIF6mW4QoKr0aAVDhzwlLBmNQWTBkiCKmZ8GbcqraqKYqg07EpiTOD8ZiBalJZcalTZ4ZxBoiTRu1IkR1CBTPElg5cuSYYGyLa+gwIZFEBQpAGGfGmu/5xtogQEjoQt7s/ns/MDvC7vd3Hp/Vzv909SZ5IJBJBRMRglt0BRETuNRWdiBhPRScixlPRiYjxVHQiYjwVnYgYT0UnIsZT0YmI8VR0ImI8FZ2IGE9FJyLGU9GJiPFUdCJiPBWdiBhPRScixlPRiYjxVHQiYjwVnYgYT0UnIsZT0YmI8VR0ImI8FZ2IGE9FJyLGU9GJiPFUdCJiPBWdiBhPRScixlPRiYjxVHQiYjwVnYgYT0UnIsZT0YmI8VR0ImI8FZ2IGE9FJyLGU9GJiPFUdCJiPBWdiBhPRScixlPRiXEiEei4Fv1TBFxUdOFwmLKyMiZNmsTAgQPJysoiGAySmZnJypUr7Y4nDtDWAkd2wbuboeafoPYH8Mm70P5/dicTuyXYHaCvCgsLqaqqYv369eTk5FBXV8eKFStoaWlhzZo1dscTm7U2wMdvQyQMfDGT67gKnx2E5iOQsxxShtsaUWzkiUScP8EvLy/n6aefpra2ltzc3M7xxYsXU1VVxf79+5k+fbqNCcVO1y7De1uip6u35IGkZPjqX4PlmnMY6U+u+LKXlJSQl5fXpeQAJk6cSGJiIoFAAIATJ06Qm5tLRkYGU6dOZd++fXbElThrPtJLyQFE4MpFOHc8bpHEYRxfdE1NTdTX17N06dJujzU2NuL3+0lKSgKgqKiI5cuXEwqF2LJlC0899RRXr17t0348Ho8Wly4/+eG/Ew539Pr1DYc72Pjtf7Y9q5a7W+6UK4oOIC0trct4e3s7wWCQ7OxsAM6dO8d7771HYWEhALNmzWLkyJHU1NTEN7DEnddKAHr/nyBCBK83MT6BxHEcfzPC5/MBEAqFWLBgQed4aWkpzc3N5OTkANHZ3YgRIzpndwDjx4/n5MmTfdqPCy5VSg8+DcLJX/e+jtdKYO2LRWyuLIpPKHEUxxddeno6gUCAkpIShg4dyqhRo6isrKS6uhqgs+jk/jUq6/ZFZyVA2uT45BHncfypq2VZVFRU4Pf7KS4upqCgAJ/Px+rVq/F6vZ03IsaOHcuZM2e4cuVK53MbGhoYN26cXdElTganwoQ/6X2dyfMgIan3dcRcrvh4ya3k5+dz6NAhDh8+3Dk2b948Fi1axKpVq6irq2PJkiWcOHGCAQMG2JhU4uXUb6ChDi5fvDE2ZBhMeByGT7Qvl9jPtUU3efJkZs6cybZt2zrHjh8/zrPPPsvp06cZMGAAr7/+erePpIjZImF459Xo32fkRz8kfBc368QQjr9GdyttbW2EQiFWrVrVZTw9PZ29e/falEqcwPN7F2P+YIR9OcRZXFl0ycnJdHT0/rkpEZEvOf5mhIjI3VLRiYjxVHQiYjwVnYgYT0UnIsZT0YmI8VR0ImI8FZ2IGE9FJyLGU9GJiPFUdCJiPBWdiBhPRScixlPRiYjxVHQiYjwVnYgYT0UnIsZT0YmI8VR0ImI8FZ2IGE9FJyLGU9GJiPFUdCJiPBWdiBhPRScixlPRiYjxVHQiYjwVnYgYT0UnIsZT0YmI8VR0ImI8FZ2IGE9FJ0Zpa7nx9+N10P5b+7KIc7im6MLhMGVlZUyaNImBAweSlZVFMBgkMzOTlStX2h1PbHb9Khx6C/7zxzfGjtfBf/wI/nsPhDvsyyb2S7A7QF8VFhZSVVXF+vXrycnJoa6ujhUrVtDS0sKaNWvsjic2ikTg8C/g/MlbP37qEBCByfPiGkscxBVFV15ezvbt26mtrSU3NxeAOXPmcPDgQaqqqsjOzrY5odjpwmc9l9yXTh2GcTNgcGp8MomzuOLUtaSkhLy8vM6S+9LEiRNJTEwkEAgA8NJLL5GRkYFlWVRWVtoRVWzQXA94+rDekXseRRzK8UXX1NREfX09S5cu7fZYY2Mjfr+fpKQkAPLy8ti9ezdPPPFEzPvxeDxaXLrsfHsP4XC4169vR8d1Xt/8hu1Ztdzdcqccf+ra1NQEQFpaWpfx9vZ2gsEg8+fP7xybNWtWXLOJM7S1XyASCYOn5/dtj2Vx8dL5OKYSJ3F80fl8PgBCoRALFizoHC8tLaW5uZmcnJx+2U8kEumX7Uj8nf00ejOiN5bH4tVtL/DG8BfiE0ocxfFFl56eTiAQoKSkhKFDhzJq1CgqKyuprq4G6LeiE/fyTYAhw+Dz80AP71fDxkPK8LjGEgdx/DU6y7KoqKjA7/dTXFxMQUEBPp+P1atX4/V6O29EyP3LsuCRJTBk6E0PfHFJJ3UMTF0Y91jiII6f0QFkZGRQU1PTZSw/P58pU6YwaNAgm1KJkwxMgUf/Es4dg8M7omNpfwRf8cPQcXAX17HFAI6f0fXkwIED3U5b169fz+jRo3n//fcpKipi9OjRHDt2zKaEEm+WF4Zn3Pj3w1+HYQ+p5MSlRdfW1kYoFOr2QeGNGzfS1NTElStXaG1tpampiQkTJtiUUkScwhWnrjdLTk6mo0PfvCgifePKGZ2ISCxUdCJiPBWdiBhPRScixlPRiYjxVHQiYjwVnYgYT0UnIsZT0YmI8VR0ImI8FZ2IGE9FJyLGU9GJiPFUdCJiPBWdiBhPRScixlPRiYjxVHQiYjwVnYgYT0UnIsZT0YmI8Vz5W8Ds9Hef/BeHLl6M+36zUlL4fuaUO3pu1QE4daGfA/XRqAfhm39sz77t4NbX2o3HdSxUdDE6dPEiey+ctztGTE5dgGNn7U5xf3Dra+3G4zoWOnUVEeOp6ETEeCo6MUYkApd/d+PfrSfhyuf25RHn0DU6cb22Fmg6BGc+gWvtN8Y/qoj+mZQCX5kMo7Jg0AP2ZBR7qejEta5fgVAt/O9vel/vykU4sR9O/BoemgHpj4GlI/++oi+3uNLnrfDRz7ueqt5WBE58AOca4JHFkDTknsUTh9E1OnGdS7+FD/8txpL7PW1no8+/eql/c4lzqejEVcJhqP9l7yU1d2106c2l8/A/e6I3MMR8KjpxlcYD8Lsz/bOts5/C2VD/bEuczVVFFw6HKSsrY9KkSQwcOJCsrCyCwSCZmZmsXLnS7njdRK5d49q3/oaOLW90Ge94622u/cUzRNrabErWu8pNs9n/9qY+j8dLuCNadP3pxH57Z3VOfa1748bj2lVFV1hYyMaNGykqKmLXrl0sW7aMFStWcPz4cXJycuyO140nMZGE736b8M5qwh99DECkoYHw1h/j/c5aPMnJNid0l5ZP+/+62sUz0UX6zo3HtWuKrry8nO3bt7Njxw7Wrl3LnDlzWLduHY899hjXr18nOzvb7oi35HloHNZfPUNH2T8SOX+e6997BevJb2AFptodzXXOf3aPttt4b7ZrMrcd164pupKSEvLy8sjNze0yPnHiRBITEwkEAly4cIGFCxeSkZFBVlYW8+bN4+jRozYlvsFa9CSesWO4XrQavF6sZ/LtjuRKF0/fo+1qRndH3HRcu+JzdE1NTdTX1/P88893e6yxsRG/309SUhLt7e0899xzzJ07F4DXXnuNgoIC9u3bd9t9eDyePmXxvvI9rKxATPk9Hg+ewFQiHx7EemoZnsTEmJ4PUFtbi2f6zJifB7B4XQ2jJ8+O6Tn7f/H3fFhd1mXs2uU2xj48N6btBIO1/O28OTE9pyf/sq6R4aljuoz1dne1p8d+1fU/iz279hL4s9xbrxwjt77WbjmuI3d4QdU1RQeQlpbWZby9vZ1gMMj8+fMBSE1N7Sw5gFmzZlFaWhq/oD2INDQQ/tm/Yi1fSvinP8N6/Kt4hg+3O1avZjy5jhmLXuwyVrlptj1hvuChb29GTtluXznxte4LNx3Xrig6n88HQCgUYsGCBZ3jpaWlNDc393gjYvPmzSxatKhP++jrO8XcAx/E9HO7IlevRa9ffHMR3oJniFy4QMcrr+L9hxI8Vt+vHMyePZtf3eG72Q/22Pcz0nJzZ1O5qX9ua37wk+6nmTfPzuDGTO5Wj93Kn37tcSI/7J+Mbn2t3Xhcx8IV1+jS09MJBAKUlJTw5ptv8s4771BcXMzWrVsBbll0GzZs4OjRo7bP6MJbt+FJSMDK/3MAvKu+ReT0GcI/f8vWXG6Uco8mCylpt19HunLbce2KorMsi4qKCvx+P8XFxRQUFODz+Vi9ejVer5dAoOu1hU2bNrFz5052797N4MGDbUoN4Y8+Jly9G+93v4MnITp59gwejPeFtYTf/CmRhgbbsrnRg2Nuv84dbXf0vdmuqdx4XLvi1BUgIyODmpqaLmP5+flMmTKFQYMGdY5t2LCB6upq9uzZQ2pqarxjdmE9Mg1rR1X38Yf9WL905jsfwJIXa2Maj5fhGfDJu3D9cv9tM9kHD4zsv+3FyqmvdW/ceFy7YkbXkwMHDnQ5bT1y5Agvv/wyra2tzJ49m2nTpjFt2jQbE0p/8ibA2H7+uOS46dDHG+7iYq6Z0d2sra2NUCjEqlWrOsf8fv8d334Wd3jo0ej3p7adu/ttDRsPaff+F1CJA7i26JKTk+no6LA7hsSZ5YWHF8KB8ugP3ryVvtxtHfQATPmaZnP3C1efusr9KdkHOcthwB3eZxr8IGQvgyTnfUum3CMqOnGllOEw81kYkRnb80Y/Ao/m63dH3G9ce+oqMmAwTP0GjMmBpo+j1+7C17uvl5AEaZNhdBYk/2H8c4r9VHTieqkjo0s4Dy61wufno4XnTYQhvuipqq7F3d9UdGIMy4rO2DRrk5vpGp2IGE9FJyLG06lrjLJSUly331EP9mMQF+3bDm59rd14XMfCE9G3EoiI4XTqKiLGU9GJiPFUdCJiPBWdiBhPRScixlPRiYjxVHQiYjwVnYgYT0UnIsZT0YmI8VR0ImI8FZ2IGE9FJyLGU9GJiPFUdCJiPBWdiBhPRScixlPRiYjxVHQiYjwVnYgYT0UnIsb7f357L4P5gLhhAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f3552953b70>"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from qiskit.aqua.components.oracles import LogicalExpressionOracle\n",
    "\n",
    "# `Oracle` (`LogicalExpressionOracle`) as the `oracle` argument\n",
    "expression = '(a & b)'\n",
    "oracle = LogicalExpressionOracle(expression)\n",
    "grover = Grover(oracle=oracle)\n",
    "grover.grover_operator.oracle.draw(output='mpl')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "tags": []
   },
   "source": [
    "You can observe, that this oracle is actually implemented with three qubits instead of two!\n",
    "\n",
    "That is because the `LogicalExpressionOracle` is not a phase-flip oracle (which flips the phase of the good state) but a bit-flip oracle. This means it flips the state of an auxiliary qubit if the other qubits satisfy the condition.\n",
    "For Grover's algorithm, however, we require a phase-flip oracle. To convert the bit-flip oracle to a phase-flip oracle we sandwich the controlled-NOT by $X$ and $H$ gates, as you can see in the circuit above.\n",
    "\n",
    "**Note:** This transformation from a bit-flip to a phase-flip oracle holds generally and you can use this to convert your oracle to the right representation."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Amplitude amplification\n",
    "Grover's algorithm uses Hadamard gates to create the uniform superposition of all the states at the beginning of the Grover operator $\\mathcal{Q}$. If some information on the good states is available, it might be useful to not start in a uniform superposition but only initialize specific states. This, generalized, version of Grover's algorithm is referred to _Amplitude Amplification_.\n",
    "\n",
    "In Qiskit, the initial superposition state can easily be adjusted by setting the `state_preparation` argument.\n",
    "\n",
    "### State preparation\n",
    "\n",
    "A `state_preparation` argument is used to specify a quantum circuit that prepares a quantum state for the start point of the amplitude amplification.\n",
    "By default, a circuit with $H^{\\otimes n} $ is used to prepare uniform superposition (so it will be Grover's search). The diffusion circuit of the amplitude amplification reflects `state_preparation` automatically."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "state preparation circuit:\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f3552953208>"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "# Specifying `state_preparation` \n",
    "# to prepare a superposition of |01>, |10>, and |11>\n",
    "oracle = QuantumCircuit(3)\n",
    "oracle.h(2)\n",
    "oracle.ccx(0,1,2)\n",
    "oracle.h(2)\n",
    "\n",
    "theta = 2 * np.arccos(1 / np.sqrt(3))\n",
    "state_preparation = QuantumCircuit(3)\n",
    "state_preparation.ry(theta, 0)\n",
    "state_preparation.ch(0,1)\n",
    "state_preparation.x(1)\n",
    "state_preparation.h(2)\n",
    "\n",
    "# we only care about the first two bits being in state 1, thus add both possibilities for the last qubit\n",
    "grover = Grover(oracle=oracle, state_preparation=state_preparation, good_state=['110', '111'])\n",
    "\n",
    "# state_preparation\n",
    "print('state preparation circuit:')\n",
    "grover.grover_operator.state_preparation.draw(output='mpl')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Success!\n",
      "Top measurement: 111\n"
     ]
    }
   ],
   "source": [
    "result = grover.run(quantum_instance=qasm_simulator)\n",
    "print('Success!' if result.oracle_evaluation else 'Failure!')\n",
    "print('Top measurement:', result.top_measurement)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Full flexibility\n",
    "\n",
    "For more advanced use, it is also possible to specify the entire Grover operator by setting the `grover_operator` argument. This might be useful if you know more efficient implementation for $\\mathcal{Q}$ than the default construction via zero reflection, oracle and state preparation.\n",
    "\n",
    "The `qiskit.circuit.library.GroverOperator` can be a good starting point and offers more options for an automated construction of the Grover operator. You can for instance \n",
    "* set the `mcx_mode` \n",
    "* ignore qubits in the zero reflection by setting `reflection_qubits`\n",
    "* explicitly exchange the $\\mathcal{S_f}, \\mathcal{S_0}$ and $\\mathcal{A}$ operations using the `oracle`, `zero_reflection` and `state_preparation` arguments"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "For instance, imagine the good state is a three qubit state $|111\\rangle$ but we used 2 additional qubits as auxiliary qubits. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f3552818ef0>"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from qiskit.circuit.library import GroverOperator, ZGate\n",
    "\n",
    "oracle = QuantumCircuit(5)\n",
    "oracle.append(ZGate().control(2), [0, 1, 2])\n",
    "oracle.draw(output='mpl')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Then, per default, the Grover operator implements the zero reflection on all five qubits."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "tags": [
     "nbsphinx-thumbnail"
    ]
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f355271acc0>"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grover_op = GroverOperator(oracle, insert_barriers=True)\n",
    "grover_op.draw(output='mpl')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "But we know that we only need to consider the first three:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f35525568d0>"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grover_op = GroverOperator(oracle, reflection_qubits=[0, 1, 2], insert_barriers=True)\n",
    "grover_op.draw(output='mpl')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Dive into other arguments of `Grover`\n",
    "`Grover` has arguments other than `oracle` and `state_preparation`. We will explain them in this section.\n",
    "\n",
    "### Specifying `good_state`\n",
    "`good_state` is used to check whether the measurement result is correct or not internally. It can be a list of binary strings, a list of integer, `Statevector`, and Callable. If the input is a list of bitstrings, each bitstrings in the list represents a good state. If the input is a list of integer, each integer represent the index of the good state to be $|1\\rangle$. If it is a `Statevector`, it represents a superposition of all good states.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n"
     ]
    }
   ],
   "source": [
    "# a list of binary strings good state\n",
    "oracle = QuantumCircuit(2)\n",
    "oracle.cz(0, 1)\n",
    "good_state = ['11', '00']\n",
    "grover = Grover(oracle=oracle, good_state=good_state)\n",
    "print(grover.is_good_state('11'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n"
     ]
    }
   ],
   "source": [
    "# a list of integer good state\n",
    "oracle = QuantumCircuit(2)\n",
    "oracle.cz(0, 1)\n",
    "good_state = [0, 1]\n",
    "grover = Grover(oracle=oracle, good_state=good_state)\n",
    "print(grover.is_good_state('11'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n"
     ]
    }
   ],
   "source": [
    "from qiskit.quantum_info import Statevector\n",
    "\n",
    "# `Statevector` good state\n",
    "oracle = QuantumCircuit(2)\n",
    "oracle.cz(0, 1)\n",
    "good_state = Statevector.from_label('11')\n",
    "grover = Grover(oracle=oracle, good_state=good_state)\n",
    "print(grover.is_good_state('11'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n"
     ]
    }
   ],
   "source": [
    "# Callable good state\n",
    "def callable_good_state(bitstr):\n",
    "    if bitstr == \"11\":\n",
    "        return True\n",
    "    return False\n",
    "\n",
    "oracle = QuantumCircuit(2)\n",
    "oracle.cz(0, 1)\n",
    "grover = Grover(oracle=oracle, good_state=callable_good_state)\n",
    "print(grover.is_good_state('11'))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### The number of `iterations`\n",
    "\n",
    "The number of repetition of applying the Grover operator is important to obtain the correct result with Grover's algorithm. The number of iteration can be set by the `iteration` argument of `Grover`. The following inputs are supported:\n",
    "* an integer to specify a single power of the Grover operator that's applied\n",
    "* or a list of integers, in which all these different powers of the Grover operator are run consecutively and after each time we check if a correct solution has been found\n",
    "\n",
    "Additionally there is the `sample_from_iterations` argument. When it is `True`, instead of the specific power in `iterations`, a random integer between 0 and the value in `iteration` is used as the power Grover's operator. This approach is useful when we don't even know the number of solution.\n",
    "\n",
    "For more details of the algorithm using `sample_from_iterations`, see [4].\n",
    "\n",
    "**References:**\n",
    "\n",
    "[4]: Boyer et al., Tight bounds on quantum searching [arxiv:quant-ph/9605034](https://arxiv.org/abs/quant-ph/9605034)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "# integer iteration\n",
    "oracle = QuantumCircuit(2)\n",
    "oracle.cz(0, 1)\n",
    "grover = Grover(oracle=oracle, good_state=['11'], iterations=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "# list iteration\n",
    "oracle = QuantumCircuit(2)\n",
    "oracle.cz(0, 1)\n",
    "grover = Grover(oracle=oracle, good_state=['11'], iterations=[1, 2, 3])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "# using sample_from_iterations\n",
    "oracle = QuantumCircuit(2)\n",
    "oracle.cz(0, 1)\n",
    "grover = Grover(oracle=oracle, good_state=['11'], iterations=[1, 2, 3], sample_from_iterations=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "When the number of solutions is known, we can also use a static method `optimal_num_iterations` to find the optimal number of iterations. Note that the output iterations is an approximate value. When the number of qubits is small, the output iterations may not be optimal.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "12"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "iterations = Grover.optimal_num_iterations(num_solutions=1, num_qubits=8)\n",
    "iterations"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Applying `post_processing`\n",
    "We can apply an optional post processing to the top measurement for ease of readability. It can be used e.g. to convert from the bit-representation of the measurement `[1, 0, 1]` to a DIMACS CNF format `[1, -2, 3]`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, -2, 3]"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def to_DIAMACS_CNF_format(bit_rep):\n",
    "    return [index+1 if val==1 else -1 * (index + 1) for index, val in enumerate(bit_rep)]\n",
    "\n",
    "oracle = QuantumCircuit(2)\n",
    "oracle.cz(0, 1)\n",
    "grover = Grover(oracle=oracle, good_state=['11'],post_processing=to_DIAMACS_CNF_format)\n",
    "grover.post_processing([1, 0, 1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<h3>Version Information</h3><table><tr><th>Qiskit Software</th><th>Version</th></tr><tr><td>Qiskit</td><td>0.23.0</td></tr><tr><td>Terra</td><td>0.16.0</td></tr><tr><td>Aer</td><td>0.7.0</td></tr><tr><td>Ignis</td><td>0.5.0</td></tr><tr><td>Aqua</td><td>0.8.0</td></tr><tr><td>IBM Q Provider</td><td>0.11.0</td></tr><tr><th>System information</th></tr><tr><td>Python</td><td>3.6.1 |Continuum Analytics, Inc.| (default, May 11 2017, 13:09:58) \n",
       "[GCC 4.4.7 20120313 (Red Hat 4.4.7-1)]</td></tr><tr><td>OS</td><td>Linux</td></tr><tr><td>CPUs</td><td>1</td></tr><tr><td>Memory (Gb)</td><td>5.827335357666016</td></tr><tr><td colspan='2'>Sun Nov 08 17:30:57 2020 EST</td></tr></table>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<div style='width: 100%; background-color:#d5d9e0;padding-left: 10px; padding-bottom: 10px; padding-right: 10px; padding-top: 5px'><h3>This code is a part of Qiskit</h3><p>&copy; Copyright IBM 2017, 2020.</p><p>This code is licensed under the Apache License, Version 2.0. You may<br>obtain a copy of this license in the LICENSE.txt file in the root directory<br> of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.<p>Any modifications or derivative works of this code must retain this<br>copyright notice, and modified files need to carry a notice indicating<br>that they have been altered from the originals.</p></div>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import qiskit.tools.jupyter\n",
    "%qiskit_version_table\n",
    "%qiskit_copyright"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
